package graphs;

import java.awt.Color;
import java.awt.Graphics;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;

import javax.swing.JComponent;

import error.GedivaException;

/**
 * abstract class that is the basis for each of the graphs the graph has
 * parameters x and y that characterize the data types
 * 
 * @author lindsaykubasik, Trevor Terris
 * 
 * @param <X>
 * @param <Y>
 */
public abstract class AbstractGraph<X, Y> extends JComponent
{
    private static final long serialVersionUID = 1L;
    private Random rand = new Random();
    protected Map<Object, List<Object>> myData;
    protected List<String> myLabels;
    protected Set<Object> myXvals;

    /*
     * (non-Javadoc)
     * 
     * @see java.awt.Component#toString()
     */
    public abstract String toString();

    /**
     * generates a random color
     * 
     * @return a random color
     */
    public Color randomColor()
    {
        int red = 255;
        int green = 255;
        int blue = 255;
        while ((red + green + blue) / 3 > 240) // makes sure all the colors are
        // visible on
        { // a white background
            red = rand.nextInt(256);
            green = rand.nextInt(256);
            blue = rand.nextInt(256);
        }
        return (new Color(red, green, blue));
    }

    /**
     * find the min and max y values for a given set of data
     * 
     * @param myData
     * @param myXvals
     * @param colors
     * @return double array representing min and max y values
     */
    protected double[] findYMinMax(Map<Object, List<Object>> myData,
            Set<Object> myXvals, List<Color> colors)
    {
        double yVal;
        double yMin = 0, yMax = 0;
        double[] yMinMax = new double[2];
        for (Object x : myXvals)
        {
            for (int i = 0; i < myData.get(x).size(); i++)
            {
                colors.add(randomColor());
                if (!(myData.get(x).get(i) instanceof Double))
                    throw new GedivaException("Improper data types.");
                yVal = (Double) myData.get(x).get(i);
                if (yVal > yMax)
                {
                    yMinMax[0] = yVal;
                    yMax = yVal;
                }
                if (yVal < yMin)
                {
                    yMinMax[1] = yVal;
                    yMin = yVal;
                }
            }
        }
        return yMinMax;
    }

    /**
     * method that the GUI calls to draw the graphs
     * 
     * @param data
     * @param labels
     */
    public void draw(Map<Object, List<Object>> data, List<String> labels)
    {
        myData = data;
        myLabels = labels;
        myXvals = myData.keySet();
        repaint();
    }

    protected abstract void paintComponent(Graphics g);

}
